import sys
import os
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                           QHBoxLayout, QPushButton, QLabel, QFileDialog, 
                           QProgressBar, QMessageBox, QSpinBox, QComboBox,
                           QDoubleSpinBox, QGroupBox, QListWidget, QListWidgetItem,
                           QTextEdit, QTabWidget)
from PyQt6.QtCore import Qt, QThread, pyqtSignal, QUrl, QTimer, QSize
from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput
from audio_splitter import split_audio_by_srt, split_audio_by_volume, time_to_milliseconds
import srt
from pydub import AudioSegment
import re
import time

class AudioSplitterThread(QThread):
    progress = pyqtSignal(str, int, int, str)  # filename, current, total, temp_dir
    finished = pyqtSignal(str)  # temp_dir
    error = pyqtSignal(str)
    status = pyqtSignal(str)  # 添加状态信息信号

    def __init__(self, audio_path, srt_path, output_dir, group_size, 
                 split_method, time_threshold, volume_threshold, output_format):
        super().__init__()
        self.audio_path = audio_path
        self.srt_path = srt_path
        self.output_dir = output_dir
        self.group_size = group_size
        self.split_method = split_method
        self.time_threshold = time_threshold
        self.volume_threshold = volume_threshold
        self.output_format = output_format
        self.temp_dir = None

    def run(self):
        try:
            self.status.emit("正在初始化...")
            if self.split_method == "基于字幕批量分割":
                self.temp_dir = split_audio_by_srt(self.audio_path, self.srt_path, 
                                   self.output_dir, self.group_size,
                                   self.progress_callback, self.output_format)
            else:  # volume
                self.temp_dir = split_audio_by_volume(self.audio_path, self.output_dir,
                                    self.time_threshold, self.volume_threshold,
                                    self.progress_callback, self.output_format)
            
            if self.temp_dir:
                self.status.emit("分割完成！")
                self.finished.emit(self.temp_dir)
            else:
                self.error.emit("分割过程出错")
        except Exception as e:
            self.error.emit(str(e))

    def progress_callback(self, filename, current, total, temp_dir=None):
        if temp_dir is None and self.temp_dir:
            temp_dir = self.temp_dir
        if isinstance(filename, str):
            if "正在" in filename:
                self.status.emit(filename)
            else:
                self.status.emit(f"正在处理: {filename} ({current}/{total})")
                self.progress.emit(filename, current, total, temp_dir or self.temp_dir)

class ExportThread(QThread):
    progress = pyqtSignal(str, int)  # 状态信息, 进度值
    finished = pyqtSignal(bool, str)  # 成功/失败, 消息
    
    def __init__(self, temp_dir, output_dir, temp_files):
        super().__init__()
        self.temp_dir = os.path.normpath(temp_dir).replace('\\', '/')
        self.output_dir = os.path.normpath(output_dir).replace('\\', '/')
        self.temp_files = temp_files
        self.should_stop = False
        
    def run(self):
        try:
            print("开始导出...")
            # 复制文件到输出目录
            import shutil
            copied_files = []
            total_steps = len(self.temp_files) * 2  # 复制和删除两个步骤
            
            # 复制文件
            for i, filename in enumerate(self.temp_files, 1):
                if self.should_stop:
                    self.finished.emit(False, "导出已取消")
                    return
                    
                try:
                    src = os.path.normpath(os.path.join(self.temp_dir, filename)).replace('\\', '/')
                    # 去掉 segment_ 前缀
                    new_filename = filename.replace('segment_', '')
                    dst = os.path.normpath(os.path.join(self.output_dir, new_filename)).replace('\\', '/')
                    
                    if not os.path.exists(src):
                        continue
                        
                    if os.path.exists(dst):
                        os.remove(dst)
                        
                    # 使用 shutil.copy2 进行快速复制
                    shutil.copy2(src, dst)
                    copied_files.append(new_filename)
                    self.progress.emit(f"正在复制: {new_filename}", i)
                    
                except Exception as e:
                    print(f"复制文件 {filename} 时出错: {e}")
                    continue
            
            # 检查复制结果
            if len(copied_files) != len(self.temp_files):
                self.finished.emit(False, f"部分文件复制失败。成功: {len(copied_files)}/{len(self.temp_files)}")
                return
            
            # 删除临时文件
            for i, filename in enumerate(copied_files, len(copied_files) + 1):
                if self.should_stop:
                    self.finished.emit(False, "导出已取消")
                    return
                    
                try:
                    src = os.path.normpath(os.path.join(self.temp_dir, filename)).replace('\\', '/')
                    if os.path.exists(src):
                        os.remove(src)
                    self.progress.emit(f"正在删除: {filename}", i)
                except Exception as e:
                    print(f"删除临时文件 {filename} 时出错: {e}")
                    continue
            
            # 删除临时目录
            try:
                if not os.listdir(self.temp_dir):
                    os.rmdir(self.temp_dir)
            except Exception as e:
                print(f"删除临时目录时出错: {e}")
            
            self.finished.emit(True, f"成功导出 {len(copied_files)} 个文件！")
            
        except Exception as e:
            self.finished.emit(False, str(e))

    def stop(self):
        self.should_stop = True

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("音频分割工具")
        self.setMinimumSize(1000, 800)
        
        # 设置全局样式
        self.setStyleSheet("""
            QMainWindow {
                background-color: #f5f5f5;
            }
            QWidget {
                font-family: 'Microsoft YaHei', 'Segoe UI', sans-serif;
            }
            QGroupBox {
                font-size: 14px;
                font-weight: bold;
                border: 1px solid #ddd;
                border-radius: 5px;
                margin-top: 10px;
                padding-top: 15px;
            }
            QGroupBox::title {
                subcontrol-origin: margin;
                left: 10px;
                padding: 0 5px;
            }
            QPushButton {
                background-color: #4a86e8;
                color: white;
                border: none;
                padding: 8px 15px;
                border-radius: 4px;
                font-size: 13px;
            }
            QPushButton:hover {
                background-color: #3a76d8;
            }
            QPushButton:pressed {
                background-color: #2a66c8;
            }
            QPushButton:disabled {
                background-color: #cccccc;
            }
            QLabel {
                font-size: 13px;
            }
            QProgressBar {
                border: 1px solid #ddd;
                border-radius: 4px;
                text-align: center;
                background-color: #f0f0f0;
            }
            QProgressBar::chunk {
                background-color: #4a86e8;
                border-radius: 3px;
            }
            QListWidget {
                border: 1px solid #ddd;
                border-radius: 4px;
                background-color: white;
                padding: 5px;
            }
            QListWidget::item {
                padding: 8px;
                border-bottom: 1px solid #eee;
            }
            QListWidget::item:selected {
                background-color: #e6f0ff;
                color: black;
            }
            QTextEdit {
                border: 1px solid #ddd;
                border-radius: 4px;
                padding: 5px;
                background-color: white;
            }
            QComboBox, QSpinBox, QDoubleSpinBox {
                border: 1px solid #ddd;
                border-radius: 4px;
                padding: 5px;
                background-color: white;
            }
            # QComboBox::drop-down, QSpinBox::drop-down, QDoubleSpinBox::drop-down {
            #     border: none;
            # }
        """)

        # 创建主窗口部件
        main_widget = QWidget()
        self.setCentralWidget(main_widget)
        layout = QVBoxLayout(main_widget)
        layout.setSpacing(15)
        layout.setContentsMargins(20, 20, 20, 20)

        # 创建左右分割布局
        split_layout = QHBoxLayout()
        split_layout.setSpacing(20)
        left_layout = QVBoxLayout()
        left_layout.setSpacing(15)
        right_layout = QVBoxLayout()
        right_layout.setSpacing(15)

        # 文件选择区域
        file_group = QGroupBox("文件选择")
        file_layout = QVBoxLayout(file_group)
        file_layout.setSpacing(10)

        # 音频文件选择
        audio_layout = QHBoxLayout()
        self.audio_label = QLabel("未选择音频文件")
        self.audio_label.setStyleSheet("""
            border: 1px solid #ddd;
            border-radius: 4px;
            padding: 8px;
            background-color: white;
        """)
        self.audio_label.setMinimumHeight(35)
        audio_btn = QPushButton("选择音频文件")
        audio_btn.setMinimumWidth(120)
        audio_layout.addWidget(self.audio_label, 1)
        audio_layout.addWidget(audio_btn)
        file_layout.addLayout(audio_layout)

        # SRT文件选择
        srt_layout = QHBoxLayout()
        self.srt_label = QLabel("未选择字幕文件")
        self.srt_label.setStyleSheet("""
            border: 1px solid #ddd;
            border-radius: 4px;
            padding: 8px;
            background-color: white;
        """)
        self.srt_label.setMinimumHeight(35)
        srt_btn = QPushButton("选择字幕文件")
        srt_btn.setMinimumWidth(120)
        srt_layout.addWidget(self.srt_label, 1)
        srt_layout.addWidget(srt_btn)
        file_layout.addLayout(srt_layout)

        # 输出目录选择
        output_layout = QHBoxLayout()
        self.output_label = QLabel("未选择输出目录")
        self.output_label.setStyleSheet("""
            border: 1px solid #ddd;
            border-radius: 4px;
            padding: 8px;
            background-color: white;
        """)
        self.output_label.setMinimumHeight(35)
        output_btn = QPushButton("选择输出目录")
        output_btn.setMinimumWidth(120)
        output_layout.addWidget(self.output_label, 1)
        output_layout.addWidget(output_btn)
        file_layout.addLayout(output_layout)

        left_layout.addWidget(file_group)

        # 分割设置区域
        settings_group = QGroupBox("分割设置")
        settings_layout = QVBoxLayout(settings_group)
        settings_layout.setSpacing(15)

        # 分割方式选择
        method_layout = QHBoxLayout()
        method_label = QLabel("分割方式：")
        self.method_combo = QComboBox()
        self.method_combo.addItems(["基于字幕批量分割", "基于停顿自动分割"])
        self.method_combo.setMinimumWidth(150)
        method_layout.addWidget(method_label)
        method_layout.addWidget(self.method_combo)
        method_layout.addStretch()
        settings_layout.addLayout(method_layout)

        # 输出格式选择
        format_layout = QHBoxLayout()
        format_label = QLabel("输出格式：")
        self.format_combo = QComboBox()
        self.format_combo.addItems(["wav", "mp3"])
        self.format_combo.setMinimumWidth(150)
        format_layout.addWidget(format_label)
        format_layout.addWidget(self.format_combo)
        format_layout.addStretch()
        settings_layout.addLayout(format_layout)

        # 字幕分组设置
        self.group_box = QGroupBox("字幕设置")
        self.group_layout = QHBoxLayout()
        group_label = QLabel("每段包含句子数：")
        self.group_spin = QSpinBox()
        self.group_spin.setMinimum(1)
        self.group_spin.setMaximum(9999)
        self.group_spin.setValue(1)
        self.group_spin.setMinimumWidth(100)
        self.group_layout.addWidget(group_label)
        self.group_layout.addWidget(self.group_spin)
        self.group_layout.addStretch()
        self.group_box.setLayout(self.group_layout)
        settings_layout.addWidget(self.group_box)

        # 音量分割设置
        self.volume_box = QGroupBox("音量设置")
        volume_layout = QHBoxLayout()
        
        # 时间阈值设置
        time_label = QLabel("时间阈值(ms)：")
        self.time_spin = QSpinBox()
        self.time_spin.setMinimum(100)
        self.time_spin.setMaximum(5000)
        self.time_spin.setValue(1000)
        self.time_spin.setSingleStep(100)
        self.time_spin.setMinimumWidth(100)
        
        # 音量阈值设置
        volume_label = QLabel("音量阈值(dB)：")
        self.volume_spin = QDoubleSpinBox()
        self.volume_spin.setMinimum(-60)
        self.volume_spin.setMaximum(0)
        self.volume_spin.setValue(-30)
        self.volume_spin.setSingleStep(1)
        self.volume_spin.setMinimumWidth(100)
        
        volume_layout.addWidget(time_label)
        volume_layout.addWidget(self.time_spin)
        volume_layout.addWidget(volume_label)
        volume_layout.addWidget(self.volume_spin)
        volume_layout.addStretch()
        self.volume_box.setLayout(volume_layout)
        settings_layout.addWidget(self.volume_box)
        
        # 默认隐藏音量设置
        self.volume_box.setVisible(False)

        left_layout.addWidget(settings_group)

        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        self.progress_bar.setMinimumHeight(25)
        left_layout.addWidget(self.progress_bar)

        # 开始按钮
        self.start_btn = QPushButton("开始分割")
        self.start_btn.setMinimumHeight(45)
        self.start_btn.setStyleSheet("""
            font-size: 16px;
            font-weight: bold;
        """)
        left_layout.addWidget(self.start_btn)

        # 状态标签
        self.status_label = QLabel("")
        self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.status_label.setStyleSheet("""
            font-size: 14px;
            color: #666;
        """)
        left_layout.addWidget(self.status_label)

        # 预览区域
        preview_group = QGroupBox("预览")
        preview_layout = QVBoxLayout(preview_group)
        preview_layout.setSpacing(10)

        # 创建预览区域
        preview_tabs = QTabWidget()
        preview_tabs.setStyleSheet("""
            QTabWidget::pane {
                border: 1px solid #ddd;
                border-radius: 4px;
            }
            QTabBar::tab {
                background: #f0f0f0;
                border: 1px solid #ddd;
                padding: 8px 15px;
                margin-right: 2px;
            }
            QTabBar::tab:selected {
                background: white;
                border-bottom-color: white;
            }
        """)
        
        # 音频信息预览
        audio_info_widget = QWidget()
        audio_info_layout = QVBoxLayout(audio_info_widget)
        self.audio_info_text = QTextEdit()
        self.audio_info_text.setReadOnly(True)
        audio_info_layout.addWidget(QLabel("音频信息："))
        audio_info_layout.addWidget(self.audio_info_text)
        preview_tabs.addTab(audio_info_widget, "音频信息")

        # 字幕预览
        subtitle_widget = QWidget()
        subtitle_layout = QVBoxLayout(subtitle_widget)
        self.subtitle_text = QTextEdit()
        self.subtitle_text.setReadOnly(True)
        subtitle_layout.addWidget(QLabel("字幕预览："))
        subtitle_layout.addWidget(self.subtitle_text)
        preview_tabs.addTab(subtitle_widget, "字幕预览")

        preview_layout.addWidget(preview_tabs)
        right_layout.addWidget(preview_group)

        # 音频列表
        list_group = QGroupBox("分割结果")
        list_layout = QVBoxLayout(list_group)
        
        # 添加时长信息标签
        duration_layout = QHBoxLayout()
        self.original_duration_label = QLabel("原始时长: 0.00秒")
        self.total_duration_label = QLabel("分割后总时长: 0.00秒")
        self.duration_diff_label = QLabel("差异: 0.00秒")
        
        # 设置标签样式
        for label in [self.original_duration_label, self.total_duration_label, self.duration_diff_label]:
            label.setAlignment(Qt.AlignmentFlag.AlignRight)
            label.setStyleSheet("""
                font-weight: bold;
                color: #333;
            """)
        
        duration_layout.addWidget(self.original_duration_label)
        duration_layout.addWidget(self.total_duration_label)
        duration_layout.addWidget(self.duration_diff_label)
        
        list_layout.addLayout(duration_layout)
        
        self.audio_list = QListWidget()
        self.audio_list.setStyleSheet("""
            QListWidget::item {
                padding: 10px;
                border-bottom: 1px solid #eee;
            }
            QListWidget::item:selected {
                background-color: #e6f0ff;
                color: black;
            }
        """)
        self.audio_list.itemDoubleClicked.connect(self.play_audio)
        list_layout.addWidget(self.audio_list)

        # 播放控制
        play_layout = QHBoxLayout()
        self.play_btn = QPushButton("播放")
        self.play_btn.setMinimumWidth(100)
        self.stop_btn = QPushButton("停止")
        self.stop_btn.setMinimumWidth(100)
        play_layout.addWidget(self.play_btn)
        play_layout.addWidget(self.stop_btn)
        list_layout.addLayout(play_layout)

        # 添加导出按钮
        export_layout = QHBoxLayout()
        self.export_btn = QPushButton("导出到输出目录")
        self.export_btn.setMinimumHeight(45)
        self.export_btn.setStyleSheet("""
            font-size: 16px;
            font-weight: bold;
            background-color: #28a745;
        """)
        self.export_btn.setEnabled(False)
        self.export_btn.clicked.connect(self.export_files)
        export_layout.addWidget(self.export_btn)
        list_layout.addLayout(export_layout)

        right_layout.addWidget(list_group)

        # 添加左右布局到主布局
        split_layout.addLayout(left_layout, 1)
        split_layout.addLayout(right_layout, 1)
        layout.addLayout(split_layout)

        # 初始化变量
        self.audio_path = ""
        self.srt_path = ""
        self.output_dir = ""
        
        # 初始化媒体播放器
        self.player = QMediaPlayer()
        self.audio_output = QAudioOutput()
        self.player.setAudioOutput(self.audio_output)
        self.current_audio = None
        
        # Connect media player signals
        self.player.mediaStatusChanged.connect(self.on_media_status_changed)
        self.player.errorOccurred.connect(self.on_player_error)

        # 连接信号
        audio_btn.clicked.connect(self.select_audio)
        srt_btn.clicked.connect(self.select_srt)
        output_btn.clicked.connect(self.select_output)
        self.method_combo.currentTextChanged.connect(self.on_method_changed)
        self.group_spin.valueChanged.connect(self.on_group_size_changed)
        self.play_btn.clicked.connect(self.play_audio)
        self.stop_btn.clicked.connect(self.stop_audio)
        self.start_btn.clicked.connect(self.start_splitting)

    def on_method_changed(self, method):
        """切换分割方式时显示/隐藏相应的设置"""
        if method == "基于字幕批量分割":
            self.group_box.setVisible(True)
            self.volume_box.setVisible(False)
            self.srt_label.setEnabled(True)
            self.update_subtitle_preview()
        else:  # 基于停顿自动分割
            self.group_box.setVisible(False)
            self.volume_box.setVisible(True)
            self.srt_label.setEnabled(False)
            self.subtitle_text.clear()

    def select_audio(self):
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择音频文件", "", "音频文件 (*.wav *.mp3)"
        )
        if file_path:
            self.audio_path = os.path.normpath(file_path).replace('\\', '/')
            self.audio_label.setText(os.path.basename(file_path))
            self.update_audio_info()
            self.update_subtitle_preview()

    def select_srt(self):
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择字幕文件", "", "字幕文件 (*.srt)"
        )
        if file_path:
            self.srt_path = os.path.normpath(file_path).replace('\\', '/')
            self.srt_label.setText(os.path.basename(file_path))
            self.update_subtitle_preview()

    def select_output(self):
        dir_path = QFileDialog.getExistingDirectory(
            self, "选择输出目录"
        )
        if dir_path:
            self.output_dir = os.path.normpath(dir_path).replace('\\', '/')
            self.output_label.setText(dir_path)

    def start_splitting(self):
        """开始分割音频"""
        if not self.audio_path:
            QMessageBox.warning(self, "错误", "请先选择音频文件！")
            return
        
        if not self.output_dir:
            QMessageBox.warning(self, "错误", "请先选择输出目录！")
            return
        
        if self.method_combo.currentText() == "基于字幕批量分割" and not self.srt_path:
            QMessageBox.warning(self, "错误", "请先选择字幕文件！")
            return
        
        # 清空音频列表和时长显示
        self.audio_list.clear()
        self.total_duration_label.setText("总时长: 0.00秒")
        self.duration_diff_label.setText("差异: 0.00秒")
        
        # 禁用开始按钮，显示进度条
        self.start_btn.setEnabled(False)
        self.progress_bar.setVisible(True)
        self.progress_bar.setValue(0)
        
        # 创建并启动分割线程
        self.splitter_thread = AudioSplitterThread(
            self.audio_path,
            self.srt_path,
            self.output_dir,
            self.group_spin.value(),
            self.method_combo.currentText(),
            self.time_spin.value(),
            self.volume_spin.value(),
            self.format_combo.currentText()
        )
        
        # 连接信号
        self.splitter_thread.progress.connect(self.on_progress)
        self.splitter_thread.finished.connect(self.on_finished)
        self.splitter_thread.error.connect(self.on_error)
        self.splitter_thread.status.connect(lambda msg: self.status_label.setText(msg))
        
        # 启动线程
        self.splitter_thread.start()

    def on_progress(self, filename, current, total, temp_dir):
        """处理进度更新"""
        # 更新进度条
        self.progress_bar.setMaximum(total)
        self.progress_bar.setValue(current)
        
        # 更新音频列表
        try:
            # 获取分割后的音频文件路径（从临时目录）
            file_path = os.path.join(temp_dir, filename)
            # 读取音频文件获取时长
            audio = AudioSegment.from_file(file_path)
            duration = audio.duration_seconds
            
            # 获取对应的字幕内容
            subtitle_content = ""
            if self.method_combo.currentText() == "基于字幕批量分割":
                try:
                    with open(self.srt_path, 'r', encoding='utf-8') as f:
                        srt_content = f.read()
                    srt_content = re.sub(r'(\d{2}:\d{2}:\d{2}),(\d{3})', r'\1.\2', srt_content)
                    subtitles = list(srt.parse(srt_content))
                    
                    # 根据当前索引获取对应的字幕组
                    group_size = self.group_spin.value()
                    start_idx = (current - 1) * group_size
                    end_idx = min(start_idx + group_size, len(subtitles))
                    
                    if start_idx < len(subtitles):
                        subtitle_group = subtitles[start_idx:end_idx]
                        subtitle_content = "\n".join(sub.content for sub in subtitle_group)
                except Exception as e:
                    subtitle_content = f"无法读取字幕: {str(e)}"
            
            # 创建列表项，显示文件名、时长和字幕内容
            display_text = f"{filename} ({duration:.2f}秒)"
            if subtitle_content:
                display_text += f"\n字幕: {subtitle_content}"
            
            item = QListWidgetItem(display_text)
            item.setData(Qt.ItemDataRole.UserRole, filename)  # 保存原始文件名
            
            # 设置项目的工具提示
            item.setToolTip(display_text)
            
            # 添加到列表并设置固定高度
            self.audio_list.addItem(item)
            if subtitle_content:
                item_height = 60  # 有字幕时的高度
            else:
                item_height = 30  # 没有字幕时的高度
            item.setSizeHint(QSize(item.sizeHint().width(), item_height))
            
            # 更新总时长
            self.update_total_duration()
        except Exception as e:
            # 如果无法读取音频信息，只显示文件名
            print(f"Error reading audio info: {e}")  # 添加调试信息
            item = QListWidgetItem(filename)
            item.setData(Qt.ItemDataRole.UserRole, filename)
            self.audio_list.addItem(item)
        
        # 滚动到最新项
        self.audio_list.scrollToBottom()

    def update_total_duration(self):
        """更新总时长显示"""
        total_duration = 0.0
        for i in range(self.audio_list.count()):
            item = self.audio_list.item(i)
            text = item.text()
            
            # 使用正则表达式提取时长
            import re
            duration_match = re.search(r'\(([\d.]+)秒\)', text)
            if duration_match:
                try:
                    duration = float(duration_match.group(1))
                    total_duration += duration
                except ValueError as e:
                    print(f"时长转换错误: {e}")  # 调试信息
                    pass
            else:
                print(f"未找到时长信息")  # 调试信息
        
        self.total_duration_label.setText(f"总时长: {total_duration:.2f}秒")
        
        # 更新差异时长
        try:
            original_text = self.original_duration_label.text()
            original_match = re.search(r'([\d.]+)秒', original_text)
            if original_match:
                original_duration = float(original_match.group(1))
                diff = total_duration - original_duration
                self.duration_diff_label.setText(f"差异: {diff:.2f}秒")
            else:
                print("未找到原始时长信息")  # 调试信息
                self.duration_diff_label.setText("差异: 0.00秒")
        except Exception as e:
            print(f"计算差异时出错: {e}")  # 调试信息
            self.duration_diff_label.setText("差异: 0.00秒")

    def on_finished(self, temp_dir):
        self.start_btn.setEnabled(True)
        self.progress_bar.setVisible(False)
        self.status_label.setText("处理完成！文件已保存到临时目录，请检查并导出。")
        self.temp_dir = temp_dir
        self.export_btn.setEnabled(True)
        QMessageBox.information(self, "完成", "音频分割完成！\n请检查分割结果，确认无误后点击'导出'按钮。")

    def on_error(self, error_msg):
        self.start_btn.setEnabled(True)
        self.progress_bar.setVisible(False)
        self.status_label.setText("处理失败")
        QMessageBox.critical(self, "错误", f"处理过程中出现错误：\n{error_msg}")

    def play_audio(self):
        """播放音频文件"""
        current_item = self.audio_list.currentItem()
        if current_item:
            file_name = current_item.data(Qt.ItemDataRole.UserRole)
            if not file_name:
                file_name = current_item.text().split(" (")[0]
            
            # Get file path from temp directory or output directory
            if hasattr(self, 'temp_dir') and self.temp_dir and os.path.exists(self.temp_dir):
                file_path = os.path.normpath(os.path.join(self.temp_dir, file_name)).replace('\\', '/')
            else:
                file_path = os.path.normpath(os.path.join(self.output_dir, file_name)).replace('\\', '/')
            
            if os.path.exists(file_path):
                # Stop current playback and clear source
                if self.player.playbackState() == QMediaPlayer.PlaybackState.PlayingState:
                    self.stop_audio()
                
                # Start new playback
                self.current_audio = file_path
                self.player.setSource(QUrl.fromLocalFile(file_path))
                self.player.play()
                self.status_label.setText(f"正在播放: {file_name}")
                self.play_btn.setText("暂停")
            else:
                QMessageBox.warning(self, "错误", "音频文件不存在！")

    def stop_audio(self):
        """完全停止音频播放并释放资源"""
        try:
            print("停止音频播放")
            # 先停止播放
            if self.player.playbackState() == QMediaPlayer.PlaybackState.PlayingState:
                self.player.stop()
            
            # 重置状态
            self.current_audio = None
            self.status_label.setText("播放已停止")
            self.play_btn.setText("播放")
            
            # 使用 QTimer 延迟释放资源
            QTimer.singleShot(100, self._cleanup_player)
            
        except Exception as e:
            print(f"停止音频时出错: {e}")
            # 即使出错也继续执行
            pass
            
    def _cleanup_player(self):
        """清理播放器资源"""
        try:
            # 确保播放器已停止
            if self.player.playbackState() != QMediaPlayer.PlaybackState.StoppedState:
                self.player.stop()
            
            # 清除播放源
            self.player.setSource(QUrl())
            
            # 重置音频输出
            self.audio_output.setVolume(1.0)
            
        except Exception as e:
            print(f"清理播放器资源时出错: {e}")

    def on_media_status_changed(self, status):
        """处理媒体状态变化"""
        if status == QMediaPlayer.MediaStatus.EndOfMedia:
            # Release the file handle when playback ends
            self.stop_audio()
        elif status == QMediaPlayer.MediaStatus.LoadedMedia:
            # Media is loaded and ready to play
            pass
        elif status == QMediaPlayer.MediaStatus.InvalidMedia:
            self.status_label.setText("无法播放此音频文件")
            self.stop_audio()

    def on_player_error(self, error, error_string):
        self.status_label.setText(f"播放错误: {error_string}")
        self.stop_audio()

    def update_audio_info(self):
        """更新音频信息预览"""
        if not self.audio_path:
            self.audio_info_text.clear()
            self.original_duration_label.setText("原始时长: 0.00秒")
            return

        try:
            audio = AudioSegment.from_file(self.audio_path)
            duration = audio.duration_seconds
            channels = audio.channels
            sample_width = audio.sample_width
            frame_rate = audio.frame_rate
            
            info_text = f"文件名: {os.path.basename(self.audio_path)}\n"
            info_text += f"时长: {duration:.2f} 秒\n"
            info_text += f"声道数: {channels}\n"
            info_text += f"采样宽度: {sample_width} 字节\n"
            info_text += f"采样率: {frame_rate} Hz"
            
            self.audio_info_text.setText(info_text)
            self.original_duration_label.setText(f"原始时长: {duration:.2f}秒")
            
            # 更新差异时长
            try:
                total_duration = float(self.total_duration_label.text().split(": ")[1].replace("秒", ""))
                diff = total_duration - duration
                self.duration_diff_label.setText(f"差异: {diff:.2f}秒")
            except (ValueError, IndexError):
                self.duration_diff_label.setText("差异: 0.00秒")
                
        except Exception as e:
            self.audio_info_text.setText(f"无法读取音频信息: {str(e)}")
            self.original_duration_label.setText("原始时长: 0.00秒")
            self.duration_diff_label.setText("差异: 0.00秒")

    def update_subtitle_preview(self):
        """更新字幕预览"""
        if not self.srt_path or not self.audio_path:
            self.subtitle_text.clear()
            return

        try:
            with open(self.srt_path, 'r', encoding='utf-8') as f:
                srt_content = f.read()
            
            # 转换时间格式
            srt_content = re.sub(r'(\d{2}:\d{2}:\d{2}),(\d{3})', r'\1.\2', srt_content)
            subtitles = list(srt.parse(srt_content))
            
            # 分组字幕
            group_size = self.group_spin.value()
            grouped_subtitles = []
            for i in range(0, len(subtitles), group_size):
                group = subtitles[i:i + group_size]
                if group:
                    start_time = group[0].start
                    end_time = group[-1].end
                    content = "\n".join(sub.content for sub in group)
                    grouped_subtitles.append((start_time, end_time, content))
            
            # 显示预览
            preview_text = ""
            for i, (start, end, content) in enumerate(grouped_subtitles, 1):
                preview_text += f"分段 {i}:\n"
                preview_text += f"开始时间: {start}\n"
                preview_text += f"结束时间: {end}\n"
                preview_text += f"内容:\n{content}\n"
                preview_text += "-" * 50 + "\n"
            
            self.subtitle_text.setText(preview_text)
        except Exception as e:
            self.subtitle_text.setText(f"无法读取字幕文件: {str(e)}")

    def on_group_size_changed(self):
        """当分组大小改变时更新字幕预览"""
        if self.method_combo.currentText() == "基于字幕批量分割":
            self.update_subtitle_preview()

    def export_files(self):
        """导出文件到最终目录"""
        try:
            if not self.temp_dir or not os.path.exists(self.temp_dir):
                QMessageBox.warning(self, "错误", "临时文件不存在！")
                return

            # 立即停止所有播放并释放文件句柄
            self.stop_audio()
            self.status_label.setText("准备导出...")
            
            # 创建输出目录
            os.makedirs(self.output_dir, exist_ok=True)

            # 获取所有临时文件
            try:
                # 获取所有音频文件，不再限制文件名前缀
                temp_files = [f for f in os.listdir(self.temp_dir) if f.endswith(('.wav', '.mp3'))]
                print(f"找到临时文件: {temp_files}")  # 添加调试信息
            except Exception as e:
                QMessageBox.critical(self, "错误", f"无法访问临时文件：{str(e)}")
                return

            if not temp_files:
                QMessageBox.warning(self, "错误", "没有找到可导出的文件！")
                return
            
            # 检查目标目录中是否存在同名文件
            existing_files = []
            for filename in temp_files:
                # 去掉 segment_ 前缀
                new_filename = filename.replace('segment_', '')
                dst = os.path.normpath(os.path.join(self.output_dir, new_filename)).replace('\\', '/')
                if os.path.exists(dst):
                    existing_files.append(new_filename)
            
            # 如果存在同名文件，询问用户是否覆盖
            if existing_files:
                files_str = "\n".join(existing_files[:5])
                if len(existing_files) > 5:
                    files_str += f"\n... 等{len(existing_files)}个文件"
                    
                reply = QMessageBox.question(
                    self,
                    "文件已存在",
                    f"以下文件在目标目录中已存在：\n{files_str}\n\n是否覆盖这些文件？",
                    QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
                )
                
                if reply == QMessageBox.StandardButton.No:
                    return

            # 设置进度条
            self.progress_bar.setVisible(True)
            self.progress_bar.setMaximum(len(temp_files) * 2)  # 复制和删除两个步骤
            
            # 禁用导出按钮，防止重复点击
            self.export_btn.setEnabled(False)
            
            # 使用QTimer延迟启动导出线程
            def start_export():
                # 创建并启动导出线程
                self.export_thread = ExportThread(self.temp_dir, self.output_dir, temp_files)
                self.export_thread.progress.connect(self.on_export_progress)
                self.export_thread.finished.connect(self.on_export_finished)
                self.export_thread.start()
                
            # 使用QTimer延迟100ms后开始导出
            QTimer.singleShot(100, start_export)
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"导出过程中出现错误：\n{str(e)}")
            self.status_label.setText("导出失败！")
            self.progress_bar.setVisible(False)
            self.export_btn.setEnabled(True)  # 重新启用导出按钮

    def on_export_progress(self, status, value):
        """处理导出进度更新"""
        self.status_label.setText(status)
        self.progress_bar.setValue(value)
        # 确保界面保持响应
        QApplication.processEvents()

    def on_export_finished(self, success, message):
        """处理导出完成"""
        self.progress_bar.setVisible(False)
        
        if success:
            self.status_label.setText("导出完成！")
            self.temp_dir = None  # 清除临时目录引用
            
            # 询问是否打开输出目录
            reply = QMessageBox.question(
                self,
                "完成",
                f"{message}\n是否打开输出目录？",
                QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
            )
            if reply == QMessageBox.StandardButton.Yes:
                try:
                    # 使用 os.startfile 打开目录
                    os.startfile(self.output_dir)
                except Exception as e:
                    # 如果 os.startfile 失败，尝试使用 explorer
                    try:
                        import subprocess
                        subprocess.run(['explorer', self.output_dir], check=True)
                    except Exception as e:
                        QMessageBox.warning(self, "警告", f"无法打开输出目录：{str(e)}")
        else:
            QMessageBox.critical(self, "错误", f"导出失败：{message}")
            self.status_label.setText("导出失败！")
        
        # 重新启用导出按钮
        self.export_btn.setEnabled(True)

    def closeEvent(self, event):
        """窗口关闭时的清理工作"""
        self.stop_audio()
        self.player.setSource(QUrl())  # 确保清除播放源
        
        # 如果导出线程正在运行，停止它
        if hasattr(self, 'export_thread') and self.export_thread.isRunning():
            self.export_thread.stop()
            self.export_thread.wait()
            
        event.accept()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec()) 